-- Copyright (c) 2010, Pavel Kovar
-- All rights reserved.
--
---------------------------------------------------------------------------------------
-- This file is a part of the Witch Navigator project

-- I2C controller top level
-- Implemented  
--   * Open collector IOs
--   * Clock generator for I2C timing


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;

entity i2c_top is
    Port ( clk : in  STD_LOGIC;
           i2c_control : in  STD_LOGIC_VECTOR (31 downto 0);
           i2c_status : out  STD_LOGIC_VECTOR (31 downto 0);
           sda : inout  STD_LOGIC;
           scl : inout  STD_LOGIC);
end i2c_top;

architecture Behavioral of i2c_top is

signal scl_out, sda_in, sda_out, clk_en: std_logic;

	COMPONENT i2c_core
	PORT(
		clk : IN std_logic;
		clk_en : IN std_logic;
		sda_in : IN std_logic;
		i2c_control : IN std_logic_vector(31 downto 0);          
		sda_out : OUT std_logic;
		scl_out : OUT std_logic;
		i2c_status : OUT std_logic_vector(31 downto 0)
		);
	END COMPONENT;

component i2c_clk_en
	port (
	clk: IN std_logic;
	thresh0: OUT std_logic;
	q: OUT std_logic_VECTOR(7 downto 0));
end component;

begin

-- scl output buffer
OBUFT_scl : OBUFT
   generic map (
      DRIVE => 12,
      IOSTANDARD => "DEFAULT",
      SLEW => "SLOW")
   port map (
      O => scl,   -- Buffer output (connect directly to top-level port)
      I => '0',   -- Buffer input
      T => scl_out  -- 3-state enable input 
   );
PULLUP_scl : PULLUP
   port map (
      O => scl    -- Pullup output (connect directly to top-level port)
   );

	-- sda bidirectional buffer
IOBUF_sda : IOBUF
   generic map (
      DRIVE => 12,
      IBUF_DELAY_VALUE => "0", -- Specify the amount of added input delay for buffer, 
                               -- "0"-"12" (Spartan-3E)
                               -- "0"-"16" (Spartan-3A)
      IFD_DELAY_VALUE => "AUTO", -- Specify the amount of added delay for input register, 
                                 -- "AUTO", "0"-"6" (Spartan-3E)
                                 -- "AUTO", "0"-"8" (Spartan-3A)
      IOSTANDARD => "DEFAULT",
      SLEW => "SLOW")
   port map (
      O => sda_in,    -- Buffer output
      IO => sda,   -- Buffer inout port (connect directly to top-level port)
      I => '0', 	 -- Buffer input
      T => sda_out -- 3-state enable input, high=input, low=output 
   );
PULLUP_sda : PULLUP
   port map (
      O => sda     -- Pullup output (connect directly to top-level port)
   );

i2c_c: i2c_core PORT MAP(
		clk => clk,
		clk_en => clk_en,
		sda_in => sda_in,
		sda_out => sda_out,
		scl_out => scl_out,
		i2c_control => i2c_control,
		i2c_status => i2c_status
	);

i2cclk_en : i2c_clk_en
		port map (
			clk => clk,
			thresh0 => clk_en,
			q => open);
end Behavioral;

